package com.rajaev.dtu.tractor.app.processor;

import com.alibaba.fastjson.JSONObject;
import com.rajaev.core.util.AMapUtil;
import com.rajaev.dtu.tractor.app.service.BatteryService;
import com.rajaev.dtu.tractor.domain.entity.BatteryOnlineLogPo;
import com.rajaev.dtu.tractor.domain.entity.BatteryPo;
import com.rajaev.dtu.tractor.domain.entity.SnotiMessage;
import com.rajaev.dtu.tractor.domain.repository.mongo.DeviceGpsMongoRepository;
import com.rajaev.dtu.tractor.domain.repository.mysql.BatteryDao;
import com.rajaev.dtu.tractor.domain.repository.mysql.BatteryOnlineLogDao;
import com.rajaev.dtu.tractor.domain.repository.redis.DeviceGPSRedisRepository;
import com.rajaev.dtu.tractor.domain.repository.redis.FaultCodeRedisRepository;
import com.rajaev.dtu.tractor.infrastructure.base.enums.BatteryOnlineStatus;
import com.rajaev.dtu.tractor.infrastructure.base.enums.SnotiEventType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date;

@Component
public class SNotiMessageProcessor extends AbstractSNotiMessageProcessor {

    @Autowired
    BatteryDao batteryDao;

    @Autowired
    BatteryService  batteryService;

    @Autowired
    DeviceFaultProcessor deviceFaultProcessor;

    @Autowired
    DeviceMonitorMessageProcessor deviceMonitorMessageProcessor;

    @Autowired
    FaultCodeRedisRepository faultCodeRedisRepository;

    @Autowired
    TransactionTemplate transactionTemplate;


    @Autowired
    DeviceGpsMongoRepository deviceGpsMongoRepository;


    @Autowired
    DeviceGPSRedisRepository deviceGPSRedisRepository;


    @Override
    public BatteryPo isLogOn(SnotiMessage snotiMessage) {
        BatteryPo batteryPo = batteryDao.selectByDid(snotiMessage.getDid());
        return batteryPo;
    }

    @Override
    public BatteryPo doLogonOn(String vin, String did) {
        BatteryPo batteryPo = batteryDao.selectByVin(vin);
        if (batteryPo != null) {
            batteryDao.updateBatterDid(batteryPo.getId(), did);
            return batteryPo;
        } else {
            return null;
        }
    }


    @Override
    public void processDeviceChargeOrDischarge() {
        SnotiMessage snotiMessage = SnotiMessageContextHolder.getSnotiMessage();
        deviceMonitorMessageProcessor.doProcessDeviceElectricity(snotiMessage);
    }


    @Override
    public void parseDeviceMonitor() {
        SnotiMessage snotiMessage = SnotiMessageContextHolder.getSnotiMessage();
        deviceMonitorMessageProcessor.doProcessSnotiMonitorMessage(snotiMessage);
    }


    @Override
    public void processDeviceFault() {
        SnotiMessage snotiMessage = SnotiMessageContextHolder.getSnotiMessage();
        deviceFaultProcessor.doProcessDeviceFaultFromSnotiMessage(snotiMessage);
    }

    @Override
    public void processDeviceLogin() {
        SnotiMessage snotiMessage = SnotiMessageContextHolder.getSnotiMessage();
        SnotiEventType snotiEventType = SnotiEventType.getType(snotiMessage.getEvent_type());
        if (!SnotiEventType.ONLINE.equals(snotiEventType)) {
            return;
        }
        BatteryPo batteryPo = SnotiMessageContextHolder.getTargetBattery();
        batteryService.batteryLogin(batteryPo,snotiMessage.getMac(),new Date(new BigDecimal(snotiMessage.getCreated_at()).longValue()*1000));
    }


    @Override
    public void processDeviceGps() {
        SnotiMessage snotiMessage = SnotiMessageContextHolder.getSnotiMessage();
        BatteryPo batteryPo = SnotiMessageContextHolder.getTargetBattery();
        JSONObject gpsData = snotiMessage.getData();
        double gpsLat = gpsData.getDoubleValue("latitude");
        double gpsLng = gpsData.getDoubleValue("longitude");
        //无效的经纬度，中国经度范围：73°33′E至135°05′E。纬度范围：3°51′N至53°33′N。不写入到redis当中
        if (AMapUtil.isValidPosition(gpsLat, gpsLng)) {

            final Point point = AMapUtil.convertToGcj02(String.valueOf(gpsLat), String.valueOf(gpsLng));
            long tickTime = new BigDecimal(snotiMessage.getCreated_at()).longValue();
            deviceGpsMongoRepository.saveDeviceGps(SnotiMessageContextHolder.getTargetBattery().getVin(), point.getY(), point.getX(), tickTime);
            deviceGPSRedisRepository.saveDeviceGPSInfo(batteryPo.getVin(), point.getX(), point.getY());
        }
    }


    @Override
    public void processDeviceTempAndCellNum() {
        SnotiMessage snotiMessage = SnotiMessageContextHolder.getSnotiMessage();
        BatteryPo batteryPo = SnotiMessageContextHolder.getTargetBattery();
        int _temperatureNums = batteryPo.getTemperatureNum();
        int _cellNums = batteryPo.getCellNum();
        SnotiEventType snotiEventType = SnotiEventType.getType(snotiMessage.getEvent_type());
        if (!SnotiEventType.KV.equals(snotiEventType)) {
            return;
        }

        if (snotiMessage.getData().containsKey("C_DCWDGS")) {
            Integer temperatureNums = snotiMessage.getData().getInteger("C_DCWDGS");
            batteryPo.setTemperatureNum(temperatureNums);
        }

        if (snotiMessage.getData().containsKey("C_DTDYGS")) {
            Integer cellNum = snotiMessage.getData().getInteger("C_DTDYGS");
            batteryPo.setCellNum(cellNum);
        }

        if (_temperatureNums == batteryPo.getTemperatureNum() && _cellNums == batteryPo.getCellNum()) {
            //数据没有发生改变
        } else {
            batteryDao.updateBatteryCellNumAndTemperatureNum(batteryPo.getId(), batteryPo.getTemperatureNum(), batteryPo.getCellNum());
        }


    }

    @Override
    public void processDeviceLogout() {
        SnotiMessage snotiMessage = SnotiMessageContextHolder.getSnotiMessage();

        SnotiEventType snotiEventType = SnotiEventType.getType(snotiMessage.getEvent_type());
        if (!SnotiEventType.OFFLINE.equals(snotiEventType)) {
            return;
        }
        BatteryPo batteryPo = SnotiMessageContextHolder.getTargetBattery();
        batteryService.batteryLogOut(batteryPo,snotiMessage.getMac(),new Date(new BigDecimal(snotiMessage.getCreated_at()).longValue()*1000));


    }


}
